From 048ed66910902da426f75e78b01555df9960b06b Mon Sep 17 00:00:00 2001 From: robertl Date: Sun, 28 Jun 2009 19:00:58 +0000 Subject: [PATCH] Add missing pieces from last commit. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@3685 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/enigma.c | 220 ++++++++++++++++++++++++++++++++++++++++ gpsbabel/pocketfms_wp.c | 129 +++++++++++++++++++++++ 2 files changed, 349 insertions(+) create mode 100755 gpsbabel/enigma.c create mode 100755 gpsbabel/pocketfms_wp.c diff --git a/gpsbabel/enigma.c b/gpsbabel/enigma.c new file mode 100755 index 000000000..fd006715f --- /dev/null +++ b/gpsbabel/enigma.c @@ -0,0 +1,220 @@ +/* + Enigma route and waypoint file format. + http://www.mglavionics.co.za/Docs/Enigma%20Waypoint%20format.pdf + Binary data are stored in little endian (Intel) + + Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +#define MYNAME "Enigma binary route and waypoint file format" + +#define WTYPE_WAYPOINT 0 // Waypoint of unspecified type +#define WTYPE_AIRPORT 1 // Typical assignment for medium sized airports +#define WTYPE_MAJORAIRPORT 2 // Typical assignment for large and international airports +#define WTYPE_SEAPLANEBASE 3 +#define WTYPE_AIRFIELD 4 // Typical assignment for smaller municipal airfields, glider fields etc +#define WTYPE_PRIVATEAIRFIELD 5 +#define WTYPE_ULTRALIGHTFIELD 6 +#define WTYPE_INTERSECTION 7 // (reporting point, boundary crossing) +#define WTYPE_HELIPORT 8 +#define WTYPE_TACAN 9 +#define WTYPE_NDBDME 10 +#define WTYPE_NDB 11 +#define WTYPE_VORDME 12 +#define WTYPE_VORTAC 13 +#define WTYPE_FANMARKER 14 +#define WTYPE_VOR 15 +#define WTYPE_REPPT 16 +#define WTYPE_LFR 17 +#define WTYPE_UHFNDB 18 +#define WTYPE_MNDB 19 +#define WTYPE_MNDBDME 20 +#define WTYPE_LOM 21 +#define WTYPE_LMM 22 +#define WTYPE_LOCSDF 23 +#define WTYPE_MLSISMLS 24 +#define WTYPE_OTHERNAV 25 // Navaid not falling into any of the above types +#define WTYPE_ALTITUDECHANGE 26 // Location at which altitude should be changed + +union wpt_data { + gbint32 wp_altitude; // Waypoint type 0-6,8: waypoint altitude in feet + gbint32 tg_altitude; // Waypoint type 26: target altitude in feet + gbuint32 frequency; // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000) + gbint32 dummy; // waypoint type 7, unused +}; + +typedef struct enigma_wpt { + gbint32 latitude; + gbint32 longitude; + union wpt_data data; + gbuint8 waypoint_type; + gbuint8 shortname_len; + char shortname[6]; + gbuint8 longname_len; + char longname[27]; +} ENIGMA_WPT; + +static gbfile *file_in, *file_out; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen_le(fname, "rb", MYNAME); +} + +gbint32 decToEnigmaPosition (double val) +{ + int degrees = fabs(val); + double frac = fabs(val) - degrees; + int enigmadeg = degrees * 180000; + int enigmafrac = 180000 * frac; + int sign = (val < 0) ? -1 : +1; + return sign * (enigmadeg + enigmafrac); +} + +float enigmaPositionToDec (gbint32 val) +{ + int deg = abs(val) / 180000; + int enigmafrac = abs(val) % 180000; + double frac = (double)enigmafrac / 180000; + int sign = (val < 0) ? -1 : +1; + return sign * (deg + frac); +} + +static void +data_read(void) +{ + struct enigma_wpt ewpt; + route_head *route = route_head_alloc(); + route_add_head (route); + + while (1 == gbfread(&ewpt, sizeof (ewpt), 1, file_in)) { + waypoint *wpt = waypt_new(); + wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude)); + wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude)); + wpt->shortname = xstrndup(ewpt.shortname, ewpt.shortname_len); + wpt->description = xstrndup(ewpt.longname, ewpt.longname_len); + switch (ewpt.waypoint_type) + { + case WTYPE_WAYPOINT: // 0 + case WTYPE_AIRPORT: // 1 + case WTYPE_MAJORAIRPORT: // 2 + case WTYPE_SEAPLANEBASE: // 3 + case WTYPE_AIRFIELD: // 4 + case WTYPE_PRIVATEAIRFIELD: // 5 + case WTYPE_ULTRALIGHTFIELD: // 6 + case WTYPE_HELIPORT: // 8 + // waypoint altitude + wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000); + break; + case WTYPE_ALTITUDECHANGE: // 26 + // target altitude + wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000); + break; + case WTYPE_INTERSECTION: // 7 + // unused + break; + default: + // frequency + // wpt->frequency = wpt.le_readu32(ewpt.data.frequency); + ; + } + route_add_wpt(route, wpt); + } +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "wb", MYNAME); +} + +static void +route_head_noop(const route_head *wp) +{ +} + +#ifndef min +#define min(a,b) ((a) < (b)) ? (a) : (b) +#endif +#ifndef max +#define max(a,b) ((a) > (b)) ? (a) : (b) +#endif + +static void +enigma_waypt_disp(const waypoint *wpt) +{ + struct enigma_wpt ewpt; + + memset (&ewpt, 0, sizeof (ewpt)); + + le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude)); + le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude)); + ewpt.waypoint_type = WTYPE_WAYPOINT; + if (wpt->altitude != unknown_alt) + le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000); + if (wpt->shortname != NULL) + { + ewpt.shortname_len = min (6, strlen (wpt->shortname)); + strncpy(ewpt.shortname, wpt->shortname, 6); + } + if (wpt->description != NULL) + { + ewpt.longname_len = min (27, strlen (wpt->description)); + strncpy(ewpt.longname, wpt->description, 27); + } + gbfwrite(&ewpt, sizeof (ewpt), 1, file_out); +} + +static void +data_write(void) +{ + route_disp_all(route_head_noop, route_head_noop, enigma_waypt_disp); +} + +static void +wr_deinit(void) +{ + gbfclose(file_in); +} + +ff_vecs_t enigma_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_read | ff_cap_write /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; diff --git a/gpsbabel/pocketfms_wp.c b/gpsbabel/pocketfms_wp.c new file mode 100755 index 000000000..c51c2e283 --- /dev/null +++ b/gpsbabel/pocketfms_wp.c @@ -0,0 +1,129 @@ +/* + PocketFMS waypoint text files (wpt). + + Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include "defs.h" +#include "csv_util.h" + +#define MYNAME "PocketFMS waypoint text file format" + +static gbfile *file_in, *file_out; + +static void +rd_init(const char *fname) +{ + file_in = gbfopen_le(fname, "r", MYNAME); +} + +double wppos_to_dec(char *value) +{ + if (strstr(value, "°") == NULL) + return atof(value); + else + { + int degrees, minutes; + float seconds; + int sign = 1; + + if (toupper(value[0]) == 'N' || toupper(value[0]) == 'E' || value[0] == '+') + { + value = &value[1]; + } + else if (toupper(value[0]) == 'S' || toupper(value[0]) == 'W' || value[0] == '-') + { + value = &value[1]; + sign = -1; + } + + sscanf(value, "%d°%d'%f\"", °rees, &minutes, &seconds); + return sign * (degrees + ((float)minutes / 60) + (seconds / 3600)); + } +} + +static void +data_read(void) +{ + char *buff; + int linecount = 0; + while ((buff = gbfgetstr(file_in))) { + char *s; + waypoint *wpt; + rtrim(buff); + if (strlen(buff) == 0) + break; + linecount++; + wpt = waypt_new(); + s = buff; + s = csv_lineparse(s, "\\w", "", linecount); + wpt->shortname = xstrdup(s); + s = csv_lineparse(NULL, "\\w", "", linecount); + wpt->latitude = wppos_to_dec(s); + s = csv_lineparse(NULL, "\\w", "", linecount); + wpt->longitude = wppos_to_dec(s); + waypt_add(wpt); + } +} + +static void +rd_deinit(void) +{ + gbfclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "w", MYNAME); +} + +static void +enigma_waypt_disp(const waypoint *wpt) +{ + gbfprintf(file_out, "%s %f %f\n", wpt->shortname, wpt->latitude, wpt->longitude); +} + +static void +data_write(void) +{ + waypt_disp_all(enigma_waypt_disp); +} + +static void +wr_deinit(void) +{ + gbfclose(file_out); +} + +ff_vecs_t pocketfms_wp_vecs = { + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_none, /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ +}; -- 2.30.2